import sys as _sys
import __builtin__

# 2.5
# http://docs.python.org/library/functions.html#all
try:
    all = all
except NameError:
    def all(iterable):
        for element in iterable:
            if not element:
                return False
        return True

# 2.5
# http://docs.python.org/library/functions.html#any
try:
    any = any
except NameError:
    def any(iterable):
        for element in iterable:
            if element:
                return True
        return False

# 2.5 - dict.__missing__ method
# http://docs.python.org/whatsnew/2.5.html#other-language-changes
if hasattr(dict, '__missing__'):
    dict = dict
else:
    class dict(__builtin__.dict):

        def __getitem__(self, key):
            try:
                return __builtin__.dict.__getitem__(self, key)
            except KeyError:
                return self.__missing__(key)

        def __missing__(self, key):
            raise KeyError(key)

# 2.6
# http://docs.python.org/library/functions.html#next
_default = object()
try:
    next = next
except NameError:
    def next(iterable, default=_default):
        if default == _default:
            return iterable.next()
        else:
            try:
                return iterable.next()
            except StopIteration:
                return default

# 2.6
# http://docs.python.org/library/functions.html#bin
# taken from: http://stackoverflow.com/questions/4069392/
try:
    bin = bin
except NameError:
    def bin(x):
        if x < 0:
            return '-' + bin(-x)
        out = []
        if x == 0:
            out.append('0')
        while x > 0:
            out.append('01'[x & 1])
            x >>= 1
            pass
        try:
            return '0b' + ''.join(reversed(out))
        except NameError, ne2:
            out.reverse()
        return '0b' + ''.join(out)


# 2.6 - property setter/deleter support
# http://docs.python.org/library/functions.html?highlight=property#property
if _sys.version_info >= (2,6):
    property = property
else:
    class property(__builtin__.property):
        __metaclass__ = type

        def __init__(self, fget, *args, **kwargs):
            super(property, self).__init__(fget, *args, **kwargs)
            self.__doc__ = fget.__doc__

        def getter(self, method):
            return property(method, self.fset, self.fdel)

        def setter(self, method):
            return property(self.fget, method, self.fdel)

        def deleter(self, method):
            return property(self.fget, self.fset, method)
